home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / C++ / DirectSound / VoiceManagement / voicemanagement.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-27  |  25.4 KB  |  699 lines

  1. //----------------------------------------------------------------------------
  2. // File: VoiceManagement.cpp
  3. //
  4. // Desc: Main application file for the VoiceManagement sample. 
  5. //
  6. // Copyright (c) Microsoft Corp. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #include "dxstdafx.h"
  9. #include <commdlg.h>
  10. #include "resource.h"
  11.  
  12.  
  13. //-----------------------------------------------------------------------------
  14. // Function-prototypes
  15. //-----------------------------------------------------------------------------
  16. INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam );
  17. VOID OnInitDialog( HWND hDlg );
  18. VOID OnOpenSoundFile( HWND hDlg );
  19. HRESULT OnPlaySound( HWND hDlg );
  20. VOID OnTimer( HWND hDlg );
  21. VOID EnablePlayUI( HWND hDlg, BOOL bShowPlayControl );
  22. VOID EnableManagementFlags( HWND hDlg, BOOL bShowFlags );
  23. VOID UpdateBehaviorText( HWND hDlg );
  24. VOID SetFileUI( HWND hDlg, TCHAR* strFileName );
  25.  
  26.  
  27.  
  28.  
  29. //-----------------------------------------------------------------------------
  30. // Defines, constants, and global variables
  31. //-----------------------------------------------------------------------------
  32. CSoundManager* g_pSoundManager = NULL;
  33. CSound*        g_pSound = NULL;
  34.  
  35.  
  36.  
  37.  
  38. //-----------------------------------------------------------------------------
  39. // Name: WinMain()
  40. // Desc: Entry point for the application.  Since we use a simple dialog for 
  41. //       user interaction we don't need to pump messages.
  42. //-----------------------------------------------------------------------------
  43. INT APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, 
  44.                       INT nCmdShow )
  45. {
  46.     InitCommonControls();
  47.  
  48.     // Display the main dialog box.
  49.     DialogBox( hInst, MAKEINTRESOURCE(IDD_MAIN), NULL, MainDlgProc );
  50.  
  51.     return TRUE;
  52. }
  53.  
  54.  
  55.  
  56.  
  57. //-----------------------------------------------------------------------------
  58. // Name: MainDlgProc()
  59. // Desc: Handles dialog messages
  60. //-----------------------------------------------------------------------------
  61. INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
  62. {
  63.     HRESULT hr;
  64.  
  65.     switch( msg ) 
  66.     {
  67.         case WM_INITDIALOG:
  68.             OnInitDialog( hDlg ); 
  69.             break;
  70.  
  71.         case WM_COMMAND:
  72.             switch( LOWORD(wParam) )
  73.             {
  74.                 case IDC_SOUNDFILE:
  75.                     OnOpenSoundFile( hDlg );
  76.                     break;
  77.  
  78.                 case IDCANCEL:
  79.                     EndDialog( hDlg, IDCANCEL );
  80.                     break;
  81.  
  82.                 case IDC_PLAY:
  83.                     // The 'play' button was pressed
  84.                     if( FAILED( hr = OnPlaySound( hDlg ) ) )
  85.                     {
  86.                         DXTRACE_ERR_MSGBOX( TEXT("OnPlaySound"), hr );
  87.                         MessageBox( hDlg, L"Error playing DirectSound buffer."
  88.                                     L"Sample will now exit.", L"DirectSound Sample", 
  89.                                     MB_OK | MB_ICONERROR );
  90.                         EndDialog( hDlg, IDABORT );
  91.                     }
  92.                     break;
  93.  
  94.                 case IDC_STOP:
  95.                     if( g_pSound )
  96.                     {
  97.                         g_pSound->Stop();
  98.                         g_pSound->Reset();
  99.                     }
  100.  
  101.                     EnablePlayUI( hDlg, TRUE );
  102.                     break;
  103.  
  104.                 case IDC_ALLOC_HARDWARE:
  105.                 case IDC_ALLOC_EITHER:
  106.                     EnableManagementFlags( hDlg, TRUE );
  107.                     UpdateBehaviorText( hDlg );
  108.                     break;
  109.  
  110.                 case IDC_ALLOC_SOFTWARE:
  111.                     EnableManagementFlags( hDlg, FALSE );
  112.                     UpdateBehaviorText( hDlg );
  113.                     break;
  114.  
  115.                 case IDC_BYTIME:
  116.                     if( IsDlgButtonChecked( hDlg, IDC_BYTIME ) == BST_CHECKED ) 
  117.                         CheckDlgButton( hDlg, IDC_BYDISTANCE, BST_UNCHECKED );
  118.                     UpdateBehaviorText( hDlg );
  119.                     break;
  120.  
  121.                 case IDC_BYDISTANCE:
  122.                     if( IsDlgButtonChecked( hDlg, IDC_BYDISTANCE ) == BST_CHECKED ) 
  123.                         CheckDlgButton( hDlg, IDC_BYTIME, BST_UNCHECKED );
  124.                     UpdateBehaviorText( hDlg );
  125.                     break;
  126.                     
  127.                 case IDC_BYPRIORTY:
  128.                     UpdateBehaviorText( hDlg );
  129.                     break;
  130.  
  131.                 default:
  132.                     return FALSE; // Didn't handle message
  133.             }
  134.             break;
  135.  
  136.         case WM_TIMER:
  137.             OnTimer( hDlg );
  138.             break;
  139.  
  140.         case WM_DESTROY:
  141.             // Cleanup everything
  142.             KillTimer( hDlg, 1 );    
  143.             SAFE_DELETE( g_pSound );
  144.             SAFE_DELETE( g_pSoundManager );
  145.             break; 
  146.  
  147.         default:
  148.             return FALSE; // Didn't handle message
  149.     }
  150.  
  151.     return TRUE; // Handled message
  152. }
  153.  
  154.  
  155.  
  156.  
  157. //-----------------------------------------------------------------------------
  158. // Name: OnInitDialog()
  159. // Desc: Initializes the dialogs (sets up UI controls, etc.)
  160. //-----------------------------------------------------------------------------
  161. VOID OnInitDialog( HWND hDlg )
  162. {
  163.     HRESULT hr;
  164.  
  165.     // Load the icon
  166. #ifdef _WIN64
  167.     HINSTANCE hInst = (HINSTANCE) GetWindowLongPtr( hDlg, GWLP_HINSTANCE );
  168. #else
  169.     HINSTANCE hInst = (HINSTANCE) GetWindowLong( hDlg, GWL_HINSTANCE );
  170. #endif
  171.     HICON hIcon = LoadIcon( hInst, MAKEINTRESOURCE( IDR_MAINFRAME ) );
  172.  
  173.     // Create a static IDirectSound in the CSound class.  
  174.     // Set coop level to DSSCL_PRIORITY, and set primary buffer 
  175.     // format to stereo, 22kHz and 16-bit output.
  176.     g_pSoundManager = new CSoundManager();
  177.     if( NULL == g_pSoundManager )
  178.     {
  179.         DXTRACE_ERR_MSGBOX( TEXT("Initialize"), E_OUTOFMEMORY );
  180.         EndDialog( hDlg, IDABORT );
  181.         return;
  182.     }
  183.  
  184.     if( FAILED( hr = g_pSoundManager->Initialize( hDlg, DSSCL_PRIORITY ) ) )
  185.     {
  186.         DXTRACE_ERR_MSGBOX( TEXT("Initialize"), hr );
  187.         MessageBox( hDlg, L"Error initializing DirectSound.  Sample will now exit.", 
  188.                           L"DirectSound Sample", MB_OK | MB_ICONERROR );
  189.         EndDialog( hDlg, IDABORT );
  190.         return;
  191.     }
  192.     
  193.     if( FAILED( hr = g_pSoundManager->SetPrimaryBufferFormat( 2, 22050, 16 ) ) )
  194.     {
  195.         DXTRACE_ERR_MSGBOX( TEXT("SetPrimaryBufferFormat"), hr );
  196.         MessageBox( hDlg, L"Error initializing DirectSound.  Sample will now exit.", 
  197.                           L"DirectSound Sample", MB_OK | MB_ICONERROR );
  198.         EndDialog( hDlg, IDABORT );
  199.         return;
  200.     }
  201.  
  202.     // Check the 'hardware' voice allocation button by default. 
  203.     CheckRadioButton( hDlg, IDC_ALLOC_EITHER, IDC_ALLOC_SOFTWARE, IDC_ALLOC_EITHER );
  204.  
  205.     HWND hEditPri = GetDlgItem( hDlg, IDC_EDIT_PRIORITY );
  206.     HWND hSpinPri = GetDlgItem( hDlg, IDC_SPIN_PRIORITY );
  207.     SendMessage( hSpinPri, UDM_SETBUDDY, (WPARAM) hEditPri, 0 );
  208.     SendMessage( hSpinPri, UDM_SETRANGE, 0, MAKELONG (0x7FFF, 0) );
  209.     SendMessage( hSpinPri, UDM_SETPOS, 0, 0 );
  210.     SendMessage( hEditPri, EM_LIMITTEXT, 5, 0 );
  211.  
  212.     // Set the icon for this dialog.
  213.     PostMessage( hDlg, WM_SETICON, ICON_BIG,   (LPARAM) hIcon );  // Set big icon
  214.     PostMessage( hDlg, WM_SETICON, ICON_SMALL, (LPARAM) hIcon );  // Set small icon
  215.  
  216.     // Create a timer, so we can check for when the soundbuffer is stopped
  217.     SetTimer( hDlg, 0, 250, NULL );
  218.  
  219.     // Set the UI controls
  220.     UpdateBehaviorText( hDlg );
  221.     SetDlgItemText( hDlg, IDC_FILENAME, TEXT("No file loaded.") );
  222. }
  223.  
  224.  
  225.  
  226.  
  227. //-----------------------------------------------------------------------------
  228. // Name: OnOpenSoundFile()
  229. // Desc: Called when the user requests to open a sound file
  230. //-----------------------------------------------------------------------------
  231. VOID OnOpenSoundFile( HWND hDlg ) 
  232. {
  233.     HRESULT hr;
  234.  
  235.     static TCHAR strFileName[MAX_PATH] = TEXT("");
  236.     static TCHAR strPath[MAX_PATH] = TEXT("");
  237.  
  238.     // Setup the OPENFILENAME structure
  239.     OPENFILENAME ofn = { sizeof(OPENFILENAME), hDlg, NULL,
  240.                          TEXT("Wave Files\0*.wav\0All Files\0*.*\0\0"), NULL,
  241.                          0, 1, strFileName, MAX_PATH, NULL, 0, strPath,
  242.                          TEXT("Open Sound File"),
  243.                          OFN_FILEMUSTEXIST|OFN_HIDEREADONLY, 0, 0,
  244.                          TEXT(".wav"), 0, NULL, NULL };
  245.  
  246.     // Get the default media path (something like C:\WINDOWS\MEDIA)
  247.     if( '\0' == strPath[0] )
  248.     {
  249.         if( GetWindowsDirectory( strPath, MAX_PATH ) != 0 )
  250.         {
  251.             if( wcscmp( &strPath[wcslen(strPath)], TEXT("\\") ) )
  252.                 wcscat( strPath, TEXT("\\") );
  253.             wcscat( strPath, TEXT("MEDIA") );
  254.         }
  255.     }
  256.  
  257.     if( g_pSound )
  258.     {
  259.         g_pSound->Stop();
  260.         g_pSound->Reset();
  261.     }
  262.  
  263.     // Update the UI controls to show the sound as loading a file
  264.     EnableWindow(  GetDlgItem( hDlg, IDC_PLAY ), FALSE);
  265.     EnableWindow(  GetDlgItem( hDlg, IDC_STOP ), FALSE);
  266.     SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Loading file...") );
  267.  
  268.     // Display the OpenFileName dialog. Then, try to load the specified file
  269.     if( TRUE != GetOpenFileName( &ofn ) )
  270.     {
  271.         SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Load aborted.") );
  272.         return;
  273.     }
  274.  
  275.     SetDlgItemText( hDlg, IDC_FILENAME, TEXT("") );
  276.  
  277.     // Free any previous sound, and make a new one
  278.     SAFE_DELETE( g_pSound );
  279.  
  280.     // Verify the file is small
  281.     HANDLE hFile = CreateFile( strFileName, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
  282.     if( hFile != NULL )
  283.     {
  284.         // If you try to open a 100MB wav file, you could run out of system memory with this
  285.         // sample cause it puts all of it into a large buffer.  If you need to do this, then 
  286.         // see the "StreamData" sample to stream the data from the file into a sound buffer.
  287.         DWORD dwFileSizeHigh = 0;
  288.         DWORD dwFileSize = GetFileSize( hFile, &dwFileSizeHigh );
  289.         CloseHandle( hFile );
  290.  
  291.         if( dwFileSizeHigh != 0 || dwFileSize > 1000000 )
  292.         {
  293.             SetDlgItemText( hDlg, IDC_FILENAME, TEXT("File too large.  You should stream large files.") );
  294.             return;
  295.         }
  296.     }
  297.  
  298.     // Load the wave file into a DirectSound buffer
  299.     if( FAILED( hr = g_pSoundManager->Create( &g_pSound, strFileName, 
  300.                                          DSBCAPS_LOCDEFER, GUID_NULL ) ) )
  301.     {
  302.         // Not a critical failure, so just update the status
  303.         DXTRACE_ERR( TEXT("Create"), hr );
  304.         SetDlgItemText( hDlg, IDC_FILENAME, TEXT("Could not create sound buffer.") );
  305.         return; 
  306.     }
  307.  
  308.     // Update the UI controls to show the sound as the file is loaded
  309.     SetDlgItemText( hDlg, IDC_FILENAME, strFileName );
  310.     EnablePlayUI( hDlg, TRUE );
  311.  
  312.     // Remember the path for next time
  313.     wcscpy( strPath, strFileName );
  314.     WCHAR* strLastSlash = wcsrchr( strPath, '\\' );
  315.     if( strLastSlash )
  316.         strLastSlash[0] = '\0';
  317. }
  318.  
  319.  
  320.  
  321.  
  322. //-----------------------------------------------------------------------------
  323. // Name: OnPlaySound()
  324. // Desc: User hit the "Play" button
  325. //-----------------------------------------------------------------------------
  326. HRESULT OnPlaySound( HWND hDlg ) 
  327. {
  328.     HRESULT hr;
  329.     LONG    lPriority;
  330.     DWORD   dwPlayFlags;
  331.     BOOL    bLooped;
  332.     BOOL    bAllocHW;
  333.     BOOL    bAllocSW;
  334.     BOOL    bAllocEither;
  335.     BOOL    bByTime;
  336.     BOOL    bByDistance;
  337.     BOOL    bByPriority;
  338.  
  339.     bLooped = ( IsDlgButtonChecked( hDlg, IDC_LOOP_CHECK ) == BST_CHECKED );
  340.  
  341.     // Determine where the buffer would like to be allocated 
  342.     bAllocHW     = ( IsDlgButtonChecked( hDlg, IDC_ALLOC_HARDWARE ) == BST_CHECKED );
  343.     bAllocSW     = ( IsDlgButtonChecked( hDlg, IDC_ALLOC_SOFTWARE ) == BST_CHECKED );
  344.     bAllocEither = ( IsDlgButtonChecked( hDlg, IDC_ALLOC_EITHER   ) == BST_CHECKED );
  345.  
  346.     if( bAllocHW || bAllocEither )
  347.     {
  348.         // Determine how the buffer should steal hardware resources (if they are not available)
  349.         bByTime      = ( IsDlgButtonChecked( hDlg, IDC_BYTIME     ) == BST_CHECKED );
  350.         bByDistance  = ( IsDlgButtonChecked( hDlg, IDC_BYDISTANCE ) == BST_CHECKED );
  351.         bByPriority  = ( IsDlgButtonChecked( hDlg, IDC_BYPRIORTY  ) == BST_CHECKED );
  352.     }
  353.     else
  354.     {
  355.         // Buffers running in software are not allowed to have
  356.         // voice management flags since they have no need to 
  357.         // steal hardware resources.
  358.         bByTime      = FALSE;
  359.         bByDistance  = FALSE;
  360.         bByPriority  = FALSE;
  361.     }
  362.  
  363.     // Get the buffer priority
  364.     TCHAR strText[MAX_PATH];
  365.     GetDlgItemText( hDlg, IDC_EDIT_PRIORITY, strText, MAX_PATH );
  366.     lPriority = _wtol( strText );
  367.  
  368.     if( lPriority < 0 || lPriority > 32767 )
  369.     {
  370.         MessageBox( hDlg, L"Please enter a buffer priority between 0 and 32767", 
  371.                     L"DirectSound Sample", MB_OK );
  372.         return S_OK;
  373.     }
  374.  
  375.     // Figure out the voice allocation flag from the dialog,
  376.     // and what the user should expect based on the dialog choice
  377.     if( bAllocSW )
  378.         dwPlayFlags = DSBPLAY_LOCSOFTWARE;
  379.  
  380.     if( bAllocHW )
  381.         dwPlayFlags = DSBPLAY_LOCHARDWARE;
  382.  
  383.     if( bAllocEither )
  384.         dwPlayFlags = 0;
  385.  
  386.     // Figure out what voice management flags should be based on the dlg
  387.     if( bByTime )
  388.     {
  389.         if( bByPriority )
  390.         {
  391.             dwPlayFlags |= DSBPLAY_TERMINATEBY_TIME | 
  392.                            DSBPLAY_TERMINATEBY_PRIORITY;
  393.         }
  394.         else
  395.         {
  396.             dwPlayFlags |= DSBPLAY_TERMINATEBY_TIME;
  397.         }
  398.     }
  399.     else if( bByDistance )
  400.     {
  401.         if( bByPriority )
  402.         {
  403.             dwPlayFlags |= DSBPLAY_TERMINATEBY_DISTANCE | 
  404.                            DSBPLAY_TERMINATEBY_PRIORITY;
  405.         }
  406.         else
  407.         {
  408.             dwPlayFlags |= DSBPLAY_TERMINATEBY_DISTANCE;
  409.         }
  410.     }
  411.     else
  412.     {
  413.         if( bByPriority )
  414.         {
  415.             dwPlayFlags |= DSBPLAY_TERMINATEBY_PRIORITY;
  416.         }
  417.         else
  418.         {
  419.             dwPlayFlags |= 0;
  420.         }
  421.     }
  422.  
  423.  
  424.     if( bLooped )
  425.         dwPlayFlags |= DSBPLAY_LOOPING;
  426.  
  427.     // Play the sound 
  428.     if( FAILED( hr = g_pSound->Play( lPriority, dwPlayFlags ) ) )
  429.     {
  430.         DXTRACE_ERR( TEXT("Play"), hr );
  431.         if( hr == DSERR_INVALIDCALL || hr == DSERR_BADFORMAT )
  432.         {
  433.             MessageBox( hDlg, L"Unsupported wave file format.", 
  434.                         L"DirectSound Sample", MB_OK | MB_ICONERROR );
  435.         }
  436.         else
  437.         {
  438.             MessageBox( hDlg, L"The buffer could not be played.", 
  439.                         L"DirectSound Sample", MB_OK | MB_ICONERROR );
  440.         }
  441.  
  442.         return S_OK;
  443.     }
  444.  
  445.     // Update the UI controls to show the sound as playing
  446.     EnablePlayUI( hDlg, FALSE );
  447.  
  448.     return S_OK;
  449. }
  450.  
  451.  
  452.  
  453.  
  454. //-----------------------------------------------------------------------------
  455. // Name: OnTimer()
  456. // Desc: When we think the sound is playing this periodically checks to see if 
  457. //       the sound has stopped.  If it has then updates the dialog.
  458. //-----------------------------------------------------------------------------
  459. VOID OnTimer( HWND hDlg ) 
  460. {
  461.     if( IsWindowEnabled( GetDlgItem( hDlg, IDC_STOP ) ) )
  462.     {
  463.         // We think the sound is playing, so see if it has stopped yet.
  464.         if( !g_pSound->IsSoundPlaying() ) 
  465.         {
  466.             // Update the UI controls to show the sound as stopped
  467.             EnablePlayUI( hDlg, TRUE );
  468.         }
  469.     }
  470. }
  471.  
  472.  
  473.  
  474.  
  475. //-----------------------------------------------------------------------------
  476. // Name: UpdateBehaviorText()
  477. // Desc: Figure out what the expected behavoir is based on the dialog,
  478. //       and display it on the dialog
  479. //-----------------------------------------------------------------------------
  480. VOID UpdateBehaviorText( HWND hDlg )
  481. {
  482.     TCHAR   strExcepted[1024];
  483.     BOOL    bAllocHW;
  484.     BOOL    bAllocSW;
  485.     BOOL    bAllocEither;
  486.     BOOL    bByTime;
  487.     BOOL    bByDistance;
  488.     BOOL    bByPriority;
  489.  
  490.     // Determine where the buffer would like to be allocated 
  491.     bAllocHW     = ( IsDlgButtonChecked( hDlg, IDC_ALLOC_HARDWARE ) == BST_CHECKED );
  492.     bAllocSW     = ( IsDlgButtonChecked( hDlg, IDC_ALLOC_SOFTWARE ) == BST_CHECKED );
  493.     bAllocEither = ( IsDlgButtonChecked( hDlg, IDC_ALLOC_EITHER   ) == BST_CHECKED );
  494.  
  495.     if( bAllocHW || bAllocEither )
  496.     {
  497.         // Determine how the buffer should steal hardware resources (if they are not available)
  498.         bByTime      = ( IsDlgButtonChecked( hDlg, IDC_BYTIME     ) == BST_CHECKED );
  499.         bByDistance  = ( IsDlgButtonChecked( hDlg, IDC_BYDISTANCE ) == BST_CHECKED );
  500.         bByPriority  = ( IsDlgButtonChecked( hDlg, IDC_BYPRIORTY  ) == BST_CHECKED );
  501.     }
  502.     else
  503.     {
  504.         // Buffers running in software are not allowed to have
  505.         // voice management flags since they have no need to 
  506.         // steal hardware resources.
  507.         bByTime      = FALSE;
  508.         bByDistance  = FALSE;
  509.         bByPriority  = FALSE;
  510.     }
  511.  
  512.     // Figure what the user should expect based on the dialog choice
  513.     if( bAllocSW )
  514.     {
  515.         wcscpy( strExcepted, L"The new sound will be played in software" );
  516.     }
  517.  
  518.     if( bAllocHW )
  519.     {
  520.         wcscpy( strExcepted, L"The new sound will be played in hardware" );
  521.     }
  522.  
  523.     if( bAllocEither )
  524.     {
  525.         wcscpy( strExcepted, L"The new sound will be played in hardware "
  526.                              L"if available" );
  527.     }
  528.  
  529.     if( bByTime )
  530.     {
  531.         if( bByPriority )
  532.         {
  533.             if( bAllocEither )
  534.             {
  535.                 wcscpy( strExcepted, L"The new sound will be played in hardware, "
  536.                                      L"if the the hardware has no available "
  537.                                      L"voices, and new sound has a higher priority "
  538.                                      L"than sounds currently playing in hardware "
  539.                                      L"then sound with the lowest priority will be "
  540.                                      L"terminated and the new sound will play in "
  541.                                      L"hardware. Otherwise, the new sound will play "
  542.                                      L"in software.  In event of a priority tie, "
  543.                                      L"then the buffer with the least time left to "
  544.                                      L"play will be prematurely terminated." );
  545.             }
  546.             else
  547.             {
  548.                 wcscat( strExcepted, L", and if the hardware has no available "
  549.                                      L"voices, the voice management buffer with "
  550.                                      L"the lowest priority as set by the "
  551.                                      L"IDirectSoundBuffer::Play priority argument "
  552.                                      L"will be prematurely terminated. In event "
  553.                                      L"of a priority tie, then the buffer with "
  554.                                      L"the least time left to play will be "
  555.                                      L"prematurely terminated." );         
  556.             }
  557.         }
  558.         else
  559.         {
  560.             wcscat( strExcepted, L", and if the hardware has no available "
  561.                                  L"voices, the voice management buffer with "
  562.                                  L"the least time left to play will be "
  563.                                  L"prematurely terminated." );                                     
  564.         }
  565.     }
  566.     else if( bByDistance )
  567.     {
  568.         if( bByPriority )
  569.         {
  570.             if( bAllocEither )
  571.             {
  572.                 wcscpy( strExcepted, L"The new sound will be played in hardware, "
  573.                                      L"if the the hardware has no available "
  574.                                      L"voices, and new sound has a higher priority "
  575.                                      L"than sounds currently playing in hardware "
  576.                                      L"then sound with the lowest priority will be "
  577.                                      L"terminated and the new sound will play in "
  578.                                      L"hardware. Otherwise, the new sound will play "
  579.                                      L"in software.  In event of a priority tie, "
  580.                                      L"then the buffer which is the furthest "
  581.                                      L"distance from the listener at the time "
  582.                                      L"of the Play will be prematurely terminated." );
  583.             }
  584.             else
  585.             {
  586.                 wcscat( strExcepted, L", and if the hardware has no available "
  587.                                      L"voices, the voice management buffer with "
  588.                                      L"the lowest priority as set by the "
  589.                                      L"IDirectSoundBuffer::Play priority argument "
  590.                                      L"will be prematurely terminated. In event "
  591.                                      L"of a priority tie, then the buffer which "
  592.                                      L"is the furthest distance from the "
  593.                                      L"listener at the time of the Play will "
  594.                                      L"be prematurely terminated." );
  595.             }
  596.         }
  597.         else
  598.         {
  599.             wcscat( strExcepted, L", and if the hardware has no available "
  600.                                  L"voices, the voice management buffer which "
  601.                                  L"is the furthest distance from the "
  602.                                  L"listener at the time of the Play will "
  603.                                  L"be prematurely terminated." );
  604.  
  605.         }
  606.     }
  607.     else
  608.     {
  609.         if( bByPriority )
  610.         {
  611.             if( bAllocEither )
  612.             {
  613.                 wcscpy( strExcepted, L"The new sound will be played in hardware, "
  614.                                      L"if the the hardware has no available "
  615.                                      L"voices, and new sound has a higher priority "
  616.                                      L"than sounds currently playing in hardware "
  617.                                      L"then sound with the lowest priority will be "
  618.                                      L"terminated and the new sound will play in "
  619.                                      L"hardware. Otherwise, the new sound will play "
  620.                                      L"in software." );
  621.             }
  622.             else
  623.             {
  624.                 wcscat( strExcepted, L", and if the hardware has no available "
  625.                                      L"voices, the voice management buffer with "
  626.                                      L"the lowest priority as set by the "
  627.                                      L"IDirectSoundBuffer::Play priority argument "
  628.                                      L"will be prematurely terminated. " );
  629.             }
  630.         }
  631.         else
  632.         {
  633.             wcscat( strExcepted, L", and the buffer will not steal any "
  634.                                  L"hardware resources." );
  635.         }
  636.     }
  637.  
  638.  
  639.     // Tell the user what to expect
  640.     SetDlgItemText( hDlg, IDC_BEHAVIOR, strExcepted );
  641. }
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648. //-----------------------------------------------------------------------------
  649. // Name: EnablePlayUI()
  650. // Desc: Enables or disables the Play UI controls 
  651. //-----------------------------------------------------------------------------
  652. VOID EnablePlayUI( HWND hDlg, BOOL bShowPlayControl )
  653. {
  654.     EnableWindow( GetDlgItem( hDlg, IDC_LOOP_CHECK ),  bShowPlayControl );
  655.     EnableWindow( GetDlgItem( hDlg, IDC_STOP ),       !bShowPlayControl );
  656.     EnableWindow( GetDlgItem( hDlg, IDC_PLAY ),        bShowPlayControl );
  657.  
  658.     // Don't allow the voice allocation or voicemanagement flags 
  659.     // to be changed when a sound is playing
  660.     EnableWindow( GetDlgItem( hDlg, IDC_BYTIME         ), bShowPlayControl );
  661.     EnableWindow( GetDlgItem( hDlg, IDC_BYDISTANCE     ), bShowPlayControl );
  662.     EnableWindow( GetDlgItem( hDlg, IDC_BYPRIORTY      ), bShowPlayControl );
  663.     EnableWindow( GetDlgItem( hDlg, IDC_EDIT_PRIORITY  ), bShowPlayControl );
  664.     EnableWindow( GetDlgItem( hDlg, IDC_ALLOC_HARDWARE ), bShowPlayControl );
  665.     EnableWindow( GetDlgItem( hDlg, IDC_ALLOC_SOFTWARE ), bShowPlayControl );
  666.     EnableWindow( GetDlgItem( hDlg, IDC_ALLOC_EITHER   ), bShowPlayControl );
  667.  
  668.     if( bShowPlayControl )
  669.     {
  670.         // If the software alloc flag is checked, then don't enable
  671.         // the voice management flags
  672.         if( IsDlgButtonChecked( hDlg, IDC_ALLOC_SOFTWARE ) == BST_CHECKED )
  673.             EnableManagementFlags( hDlg, FALSE );
  674.     }
  675.  
  676.     if( bShowPlayControl )
  677.         SetFocus( GetDlgItem( hDlg, IDC_PLAY ) );
  678.     else
  679.         SetFocus( GetDlgItem( hDlg, IDC_STOP ) );
  680. }
  681.  
  682.  
  683.  
  684.  
  685. //-----------------------------------------------------------------------------
  686. // Name: EnableManagementFlags()
  687. // Desc: Enable or disable the voice management flags
  688. //-----------------------------------------------------------------------------
  689. VOID EnableManagementFlags( HWND hDlg, BOOL bShowFlags )
  690. {
  691.     EnableWindow( GetDlgItem( hDlg, IDC_BYTIME        ), bShowFlags );
  692.     EnableWindow( GetDlgItem( hDlg, IDC_BYDISTANCE    ), bShowFlags );
  693.     EnableWindow( GetDlgItem( hDlg, IDC_BYPRIORTY     ), bShowFlags );
  694.     EnableWindow( GetDlgItem( hDlg, IDC_EDIT_PRIORITY ), bShowFlags );
  695. }
  696.  
  697.  
  698.  
  699.